#include "App_Buffer.h"

static SubBuffer *sub_buffer_init(int size)
{
    SubBuffer *sub_buffer = (SubBuffer *)malloc(sizeof(SubBuffer));
    sub_buffer->ptr = (char *)malloc(size);
    sub_buffer->size = size;
    sub_buffer->len = 0;
    return sub_buffer;
}

static void sub_buffer_swap(Buffer *buffer)
{
    // 加写锁
    log_debug("切换读/写缓冲区前， 加写锁");
    int temp = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = temp;
    // 解写锁
    log_debug("切换读/写缓冲区后， 解写锁");
    pthread_mutex_unlock(&buffer->write_lock);
}

Buffer *App_Buffer_Init(int size)
{
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));

    buffer->sub_buffers[0] = sub_buffer_init(size);
    buffer->sub_buffers[1] = sub_buffer_init(size);

    buffer->read_index = 0;
    buffer->write_index = 1;
    return buffer;
}

void App_Buffer_Free(Buffer *buffer)
{
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]);
    free(buffer);
}

int App_Buffer_Write(Buffer *buffer, char *data, int len)
{
    if (len > 255)
    {
        log_error("写入的数据的长度不能超过255");
        return -1;
    }
    // 加写锁
    log_debug("写入数据前，加写锁");
    pthread_mutex_lock(&buffer->write_lock);

    // 得到写缓冲区
    SubBuffer *w_buffer = buffer->sub_buffers[buffer->write_index];

    // 检查缓冲区是否还有足够的空间
    if ((w_buffer->size - w_buffer->len) < len + 1)
    {
        log_error("缓冲区剩余空间不足");
        // 解写锁
        pthread_mutex_unlock(&buffer->write_lock);
        return -1;
    }

    // 先写入数据长度再写入数据本身
    w_buffer->ptr[w_buffer->len] = len;
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);

    // 更新len
    w_buffer->len += len + 1;

    // 解写锁
    log_debug("写入数据后， 解写锁");
    pthread_mutex_unlock(&buffer->write_lock);
    return 0;
}

int App_Buffer_Read(Buffer *buffer, char *data_buff, int buff_size)
{

    // 加读锁
    log_debug("读取数据前， 加读锁");
    pthread_mutex_lock(&buffer->read_lock);
    // 得到读缓冲区
    SubBuffer *read_buffer = buffer->sub_buffers[buffer->read_index];

    // 如果读缓冲区为空，切换读/写缓冲区，如果还是空，则失败结束
    if (read_buffer->len == 0)
    {
        sub_buffer_swap(buffer);
        read_buffer = buffer->sub_buffers[buffer->read_index];
        if (read_buffer->len == 0)
        {
            log_error("读缓冲器为空");
            return -1;
        }
    }

    // 读取数据长度
    int len = read_buffer->ptr[0];
    log_debug("读取数据长度%d", len);

    // 如果data_buff 大小不够，失败结束
    if (buff_size < len)
    {
        log_error("data_buf大小不够");
        // 解读锁

        return -1;
    }
    // 读取后面len个字节数据到data_buff中
    memcpy(data_buff, read_buffer->ptr + 1, len);

    // 将后面未读取的数据转移到起始位置
    if (read_buffer->len > 1 + len)
    {
        memmove(read_buffer->ptr, read_buffer->ptr + 1 + len, read_buffer->len - 1 - len);
    }

    // 更新读缓冲区的len
    read_buffer->len -= len + 1;

    // 解读锁
    log_debug("读取数据后， 解读锁");
    pthread_mutex_unlock(&buffer->read_lock);
    return len;
}
